//main.cp
//g++ -o prog source.cpp `allegro-config --cppflags --libs` - linux
//draw( sprite[int(timer/ani_speed)%frames] );
#include <stdio.h>
#include <allegro.h>
#include "image.h"
#include "animation.h"
#include "stage.h"
#include "character.h"
#include "nelib.h"
#include "menu.h"
#include "option.h"
#include "sound.h"

BITMAP *buffer;
volatile int game_time;
volatile int animat_time;

void inc_game_time(){
	game_time++;
}
END_OF_FUNCTION(inc_game_time)

void inc_animat_time(){
	animat_time++;
}
END_OF_FUNCTION(inc_animat_time);

//Variavel de parametro do laço principal
int gaming = 1;

//Variavel que representa o estado dos loops
int game_state = 0;
// 0 - Menu Principal
// 1 - Menu de Fases
// 2 - Fase atual
// 3 - Morto =D

void main_menu_logic(menu *main_menu) {
   if(keypressed()) {
      int keya = readkey() >> 8;

      if(keya == KEY_UP)
         main_menu->move(0);

      if(keya == KEY_DOWN)
         main_menu->move(1);

      if(keya == KEY_ENTER) 
         sound::play(sound::menu);

      if(main_menu->selected == 0) {   
         game_state = 1;
         return;
       }

      if(main_menu->selected == 1) {
         gaming = 0;
         return;
       }

      if(keya == KEY_ESC) {
         gaming = 0;
         return;
      }

   }
   clear_keybuf();
}

void stage_menu_logic(menu *stage_menu, stage *stage_instance, character *nelson) {
   if(keypressed()) {
      int keya = readkey() >> 8;
		
      if(keya == KEY_UP)
         stage_menu->move(0);

      if(keya == KEY_DOWN)
         stage_menu->move(1);

      if(keya == KEY_ENTER) {
         sound::play(sound::menu);

         if(stage_menu->selected == 0) {
            nelson->x = 50;
            nelson->y = 350;
            stage temp("fase00.txt");
            *stage_instance = temp;
            game_state = 2;
            return;
         }

         if(stage_menu->selected == 1) {
            nelson->x = 50;
            nelson->y = 350;
            stage temp("fase01.txt");
            *stage_instance = temp;
            game_state = 2;
            return;
         }

         if(stage_menu->selected == 2) {
            nelson->x = 50;
            nelson->y = 350;
            stage temp("animefase.txt");
            *stage_instance = temp;
            game_state = 2;
            return;
         }

         if(stage_menu->selected == 3) {
            game_state = 0;
            return;
         }

      }

      if(keya == KEY_ESC) {
            game_state = 0;
            return;

      }
   }
   clear_keybuf();
}

void stage_logic(int *animat_atual, int *vely, character *nelson, stage *stage)
		 {

   int floor = 0;
   clear_keybuf();
	
   if (key[KEY_RIGHT]) {
      nelson->x = stage->collision_x(nelson->x, nelson->y, nelson->w, nelson->h
		  , (VELX * 1), &game_state);

   if (nelson->x + nelson->w > stage->w)
      nelson->x = stage->w - nelson->w;
   if ( nelson->x + nelson->w > (stage->x + 60 * (SCREEN_W/100)) ) {
         if ((stage->x + SCREEN_W) + ((nelson->x + nelson->w) - (stage->x + 60
	     * (SCREEN_W/100))) > stage->w) {

            stage->x = stage->w - SCREEN_W;

         } else {

            stage->x += (nelson->x + nelson->w) - (stage->x + 60 *
                        (SCREEN_W/100));
         }

         if (stage->w != SCREEN_W)
            stage->background->x = ( stage->x *  (stage->background->w -
                                     SCREEN_W) ) / (stage->w - SCREEN_W);
         }

      if (*animat_atual!=0){
         *animat_atual = 0;
         animat_time = 0;
      }

      nelson->count[*animat_atual] = animat_time;
   } else if (key[KEY_LEFT]) {

      nelson->x = stage->collision_x(nelson->x, nelson->y, nelson->w,
                  nelson->h, (VELX * -1), &game_state);
      
      if (nelson->x < 0)
         nelson->x = 0;

      if (nelson->x < (stage->x + 40 * (SCREEN_W/100)) ) {

         if ((stage->x) - ((stage->x + 40 * (SCREEN_W/100)) - nelson->x) < 0)
            stage->x = 0;
         else
            stage->x -= (stage->x + 40 * (SCREEN_W/100)) - nelson->x;
         if (stage->w != SCREEN_W)
            stage->background->x = (stage->x * (stage->background->w - 
                                    SCREEN_W) )/ (stage->w - SCREEN_W);

      }
		
      if (*animat_atual!=1){
         *animat_atual = 1;
         animat_time = 0;
      }
      nelson->count[*animat_atual] = animat_time;
   } else if (*animat_atual == 0)
      *animat_atual = 2;
   else if (*animat_atual == 1)
      *animat_atual = 3;

   nelson->y = stage->collision_y(nelson->x, nelson->y, nelson->w, nelson->h,
                                  vely, &floor, &game_state);

   *vely += G;

   if (key[KEY_UP] && floor) {
      *vely = -1 * JUMP;
      sound::play(sound::jump);
   }

   if(key[KEY_ESC]) {
      game_state = 1;
      return;
   }

   if(key[KEY_J]) {
      nelson->x = stage->collision_x(nelson->x, nelson->y, nelson->w, nelson->h
                                     , 200, &game_state);

      if (nelson->x + nelson->w > stage->w)
         nelson->x = stage->w - nelson->w;
      if ( nelson->x + nelson->w > (stage->x + 60 * (SCREEN_W/100)) ) {
         if ((stage->x + SCREEN_W) + ((nelson->x + nelson->w) - (stage->x + 60 
             * (SCREEN_W/100))) > stage->w) {

            stage->x = stage->w - SCREEN_W;

         } else {

            stage->x += (nelson->x + nelson->w) - (stage->x + 60 
                         * (SCREEN_W/100));
         }

         if (stage->w != SCREEN_W)
            stage->background->x = ( stage->x *  (stage->background->w 
                                     - SCREEN_W) ) / (stage->w - SCREEN_W);
         }

   } else if(key[KEY_H]) {

      nelson->x = stage->collision_x(nelson->x, nelson->y, nelson->w, nelson->h
                                     , -200, &game_state);
     	
      if (nelson->x < 0)
         nelson->x = 0;
		
      if (nelson->x < (stage->x + 40 * (SCREEN_W/100)) ) {
         if ((stage->x) - ((stage->x + 40 * (SCREEN_W/100)) - nelson->x) < 0)
            stage->x = 0;
         else
            stage->x -= (stage->x + 40 * (SCREEN_W/100)) - nelson->x;
	
         if (stage->w != SCREEN_W)
            stage->background->x = (stage->x * (stage->background->w 
                                    - SCREEN_W) )/ (stage->w - SCREEN_W);
      }
   }
}

void game_logic(int *animat_atual, int *vely, character *nelson, stage *stage,
                menu *main_menu, menu *stage_menu) {

   switch(game_state) {
      case (0):
         main_menu_logic(main_menu);
         break;
      case (1):
         stage_menu_logic(stage_menu, stage, nelson);
         break;
      case (2):
         stage_logic(animat_atual, vely, nelson, stage);
         break;
      case (3):
         if (keypressed())
            gaming = 0;
         break;
   }
}

void draw(int animat_atual, character nelson, stage stage, menu main_menu,
          menu stage_menu, menu game_over) {

   acquire_screen();
   switch(game_state) {
      case (0):
         main_menu.draw(buffer);
         break;
      case (1):
         stage_menu.draw(buffer);
         break;
      case (2):
         stage.draw_background(buffer);
         stage.draw_obj(buffer);
         nelson.draw(animat_atual, buffer, stage);
         break;
      case (3):
         game_over.draw(buffer);
         break;
   }
   draw_sprite(screen, buffer, 0, 0);
   release_screen();
}

int main() {
   int vely = 0;
   int animat_atual = 0;

   allegro_init();
   install_timer();
#ifndef NO_SOUND
   install_sound(MIDI_AUTODETECT, DIGI_AUTODETECT, NULL);
#endif

   install_keyboard();

   set_color_depth(16);
   set_gfx_mode( GFX_AUTODETECT_WINDOWED, SCREEN_W, SCREEN_H, 0, 0);

   LOCK_VARIABLE(game_time);
   LOCK_FUNCTION(inc_game_time);
   LOCK_VARIABLE(animat_time);
   LOCK_FUNCTION(inc_animat_time);

   buffer = create_bitmap(800, 600);
		
   character nelson("personagem.txt");
   stage stage("animefase.txt");
   menu main_menu("main_menu.txt");
   menu stage_menu("stage_menu.txt");
   menu game_over("game_over.txt");
      stage.play();

   install_int_ex(inc_game_time, BPS_TO_TIMER(20));
   install_int_ex(inc_animat_time, BPS_TO_TIMER(10));
	
   while(gaming) {
      while(game_time) {
         game_logic(&animat_atual, &vely, &nelson, &stage, &main_menu, &stage_menu);
         game_time--;
      }
      draw(animat_atual, nelson, stage, main_menu, stage_menu, game_over);
      while(!game_time)
         rest(1);
   }
   stage.stop_play();
   return 0;
}
END_OF_MAIN();
